#ifndef ELNOTIFICATION_H
#define ELNOTIFICATION_H

#include "../basic/elcomponent.h"
#include "../basic/eltheme.h"

class ElIcon;
class QPropertyAnimation;
class ElTextButton;
/**
 * @brief The ElNotification class
 * Same as ElMessage, don't delete any instance of ElNotification explicitly
 * because instaces would be deleted internally once they fade out.
 * The most recommending way to create instance is to use static function,
 * such as success(), warning(), etc.
 * @tip
 * It's strongly recommended that do not create instances with the same direction
 * but different offsets from each other, as this will result in a confusing layout.
 */
class ElNotification : public ElComponent
{
    Q_OBJECT
public:
    enum Type { Default, Success, Warning, Info, Error };
    enum Position { TopRight, TopLeft, BottomRight, BottomLeft };

    ElNotification(QWidget *parent);
    ElNotification(QWidget *parent,
                   const QString &title,
                   const QString &msg,
                   Type type = Default,
                   int duration = 4500,
                   Position position = TopRight,
                   bool isClosable = true,
                   int offset = 0);

    // mostly used in parent's resize event to fix their position.
    static void adjustifyAllPos();

    static void success(QWidget *parent,
                        const QString &title,
                        const QString &msg,
                        int duration = 4500,
                        Position position = TopRight,
                        bool isClosable = true,
                        int offset = 0);
    static void warning(QWidget *parent,
                        const QString &title,
                        const QString &msg,
                        int duration = 4500,
                        Position position = TopRight,
                        bool isClosable = true,
                        int offset = 0);
    static void info(QWidget *parent,
                     const QString &title,
                     const QString &msg,
                     int duration = 4500,
                     Position position = TopRight,
                     bool isClosable = true,
                     int offset = 0);
    static void error(QWidget *parent,
                      const QString &title,
                      const QString &msg,
                      int duration = 4500,
                      Position position = TopRight,
                      bool isClosable = true,
                      int offset = 0);

    QString title() const;
    void setTitle(const QString &title);

    QString message() const;
    void setMessage(const QString &msg);

    Type type() const;
    void setType(Type type);

    // returned value can also decide icon's details since it doesn't have underlying const
    ElIcon *icon() const;
    // recommend if you want to decide its details, such as icon's background.
    void setIcon(ElIcon *icon);
    // recommend if you just want to display by the given file path of an icon.
    void setIcon(const QString &fileName);

    int duration() const;
    void setDuration(int duration);

    Position position() const;
    void setPosition(Position position);

    bool isClosable() const;
    void setClosable(bool closable);

    int offset() const;
    void setOffset(int offset);

    static const int Fixed_Width;
    static const int Icon_Size;
    static const int Icon_Text_Spacing;
    static const int Padding_Lr;
    static const int Padding_Tb;
    static const int Title_Msg_Spacing;
    static const int Tb_Spacing;
    static const int Lr_Spacing;

public slots:
    void fadeIn();
    void fadeOut();

private:
    void manager_handle_notify_animation();

signals:
    void clicked();

protected:
    void paintEvent(QPaintEvent *e) override;
    void showEvent(QShowEvent *e) override;
    void enterEvent(QEnterEvent *e) override;
    void leaveEvent(QEvent *e) override;
    void mouseReleaseEvent(QMouseEvent *e) override;
    void initPalette() override;

private:
    Q_PROPERTY(QString title READ title WRITE setTitle)
    Q_PROPERTY(QString message READ message WRITE setMessage)
    Q_PROPERTY(Type type READ type WRITE setType)
    Q_PROPERTY(int duration READ duration WRITE setDuration)
    Q_PROPERTY(Position position READ position WRITE setPosition)
    Q_PROPERTY(bool closable READ isClosable WRITE setClosable)
    Q_PROPERTY(int offset READ offset WRITE setOffset)

    static QList<ElNotification *> notify_managers[4]; // there are 4 directions

    QString _title;
    QString _msg;
    ElTheme _theme;
    ElIcon *_icon = nullptr;
    int _duration = 4500;
    Position _position = TopRight;
    bool _closable = true;
    int _offset = 0;

    QPropertyAnimation *_animY = nullptr;
    QPropertyAnimation *_animOpa = nullptr;
    QPropertyAnimation *_iconAnimOpa = nullptr;
    qsizetype _no;
    QTimer *_fadeTimer = nullptr;
    ElTextButton *_closeBtn = nullptr;
    bool _is_repeat_click = false;

    void initAnimation();
    void startIconAnimation(bool isForward = true);
    void createCloseBtn();
};

#endif // ELNOTIFICATION_H
